package com.bzkj.basicinfo.service.putaway.impl;

import com.bzkj.basicinfo.domain.putaway.WmsPutawayDetailEntity;
import com.bzkj.basicinfo.domain.putaway.WmsPutawayTaskEntity;
import com.bzkj.basicinfo.domain.receive.WmsReceiveOrderDetailEntity;
import com.bzkj.basicinfo.mapper.putaway.WmsPutawayDetailMapper;
import com.bzkj.basicinfo.mapper.putaway.WmsPutawayTaskMapper;
import com.bzkj.basicinfo.mapper.receive.WmsReceiveOrderDetailMapper;
import com.bzkj.basicinfo.mapper.receive.WmsReceiveOrderMapper;
import com.bzkj.basicinfo.service.exception.WmsExceptionRecordService;
import com.bzkj.common.core.domain.AjaxResult;
import com.bzkj.common.core.page.TableDataInfo;
import com.bzkj.common.utils.DateUtils;
import com.bzkj.common.utils.StringUtils;
import com.bzkj.basicinfo.service.putaway.WmsPutawayTaskService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 上架管理服务实现类
 *
 *@author lixinyu
 * @date 2025-10-22
 */
@Service
public class WmsPutawayTaskServiceImpl implements WmsPutawayTaskService {

    @Autowired
    private WmsPutawayTaskMapper putawayTaskMapper;

    @Autowired
    private WmsPutawayDetailMapper putawayDetailMapper;

    @Autowired
    private WmsReceiveOrderDetailMapper receiveDetailMapper;

    @Autowired
    private WmsReceiveOrderMapper receiveOrderMapper;

    @Autowired
    private WmsExceptionRecordService exceptionRecordService;

    /**
     * 查询上架任务列表（分页）
     */
    @Override
    public TableDataInfo getPutawayTaskList(WmsPutawayTaskEntity entity, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<WmsPutawayTaskEntity> list = putawayTaskMapper.selectPutawayTaskList(entity);
        PageInfo<WmsPutawayTaskEntity> pageInfo = new PageInfo<>(list);

        TableDataInfo dataTable = new TableDataInfo();
        dataTable.setCode(200);
        dataTable.setMsg("查询成功");
        dataTable.setRows(list);
        dataTable.setTotal(pageInfo.getTotal());
        return dataTable;
    }

    /**
     * 根据ID查询上架任务详情（含明细）
     */
    @Override
    public AjaxResult getPutawayTaskDetail(Long id) {
        // 查询主表
        WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(id);
        if (task == null) {
            return AjaxResult.error("上架任务不存在");
        }

        // 查询明细
        List<WmsPutawayDetailEntity> detailList = putawayDetailMapper.selectPutawayDetailByTaskId(id);

        // 组装返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("task", task);
        result.put("detailList", detailList);

        return AjaxResult.success("查询成功", result);
    }

    /**
     * 创建上架任务（根据收货单明细）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createPutawayTask(Long receiveDetailId, String operator) {
        try {
            // 查询收货明细
            WmsReceiveOrderDetailEntity receiveDetail = receiveDetailMapper.selectReceiveDetailById(receiveDetailId);
            if (receiveDetail == null) {
                return AjaxResult.error("收货明细不存在");
            }

            // 检查是否已经收货
            if (!"2".equals(receiveDetail.getDetailStatus())) {
                return AjaxResult.error("收货明细未完成收货，无法创建上架任务");
            }

            // 检查是否已创建上架任务
            List<WmsPutawayTaskEntity> existTasks = putawayTaskMapper.selectPutawayTaskByReceiveDetailId(receiveDetailId);
            if (existTasks != null && !existTasks.isEmpty()) {
                return AjaxResult.error("该收货明细已创建上架任务");
            }

            // 生成上架任务号
            String putawayTaskNo = generatePutawayTaskNo();

            // 创建上架任务
            WmsPutawayTaskEntity task = new WmsPutawayTaskEntity();
            task.setPutawayTaskNo(putawayTaskNo);
            task.setReceiveOrderId(receiveDetail.getReceiveOrderId());
            task.setReceiveOrderNo(receiveDetail.getReceiveOrderNo());
            task.setReceiveDetailId(receiveDetailId);
            task.setProductId(receiveDetail.getProductId());
            task.setProductCode(receiveDetail.getProductCode());
            task.setProductName(receiveDetail.getProductName());
            task.setProductSpec(receiveDetail.getProductSpec());
            task.setManufacturer(receiveDetail.getManufacturer());
            task.setBatchCode(receiveDetail.getBatchCode());
            task.setProductDate(receiveDetail.getProductDate());
            task.setExpDate(receiveDetail.getExpDate());
            task.setPutawayQuantity(receiveDetail.getReceivedQuantity());
            task.setPutedQuantity(BigDecimal.ZERO);
            task.setUnitCode(receiveDetail.getUnitCode());
            task.setUnitName(receiveDetail.getUnitName());
            task.setTaskStatus("0"); // 0待上架
            task.setPriority(0);
            task.setCreateBy(operator);
            task.setCreateTime(new Date());

            // 推荐储位逻辑（简化版，实际应该调用储位推荐算法）
            // TODO: 实现储位推荐算法
            task.setRecommendLocationId("LOC001");
            task.setRecommendLocationCode("A-01-01");

            int rows = putawayTaskMapper.insertPutawayTask(task);
            if (rows <= 0) {
                return AjaxResult.error("创建上架任务失败");
            }

            return AjaxResult.success("创建上架任务成功", putawayTaskNo);
        } catch (Exception e) {
            throw new RuntimeException("创建上架任务异常：" + e.getMessage(), e);
        }
    }

    /**
     * 批量创建上架任务（根据收货单）
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult batchCreatePutawayTask(Long receiveOrderId, String operator) {
        try {
            // 查询收货单的所有已收货明细
            WmsReceiveOrderDetailEntity queryEntity = new WmsReceiveOrderDetailEntity();
            queryEntity.setReceiveOrderId(receiveOrderId);
            queryEntity.setDetailStatus("2"); // 已收货
            List<WmsReceiveOrderDetailEntity> detailList = receiveDetailMapper.selectReceiveDetailList(queryEntity);

            if (detailList == null || detailList.isEmpty()) {
                return AjaxResult.error("没有已收货的明细，无法创建上架任务");
            }

            int successCount = 0;
            for (WmsReceiveOrderDetailEntity detail : detailList) {
                // 检查是否已创建上架任务
                List<WmsPutawayTaskEntity> existTasks = putawayTaskMapper.selectPutawayTaskByReceiveDetailId(detail.getId());
                if (existTasks != null && !existTasks.isEmpty()) {
                    continue; // 跳过已创建的
                }

                AjaxResult result = createPutawayTask(detail.getId(), operator);
                if (result.isSuccess()) {
                    successCount++;
                }
            }

            return AjaxResult.success("批量创建上架任务成功，共创建 " + successCount + " 个任务");
        } catch (Exception e) {
            throw new RuntimeException("批量创建上架任务异常：" + e.getMessage(), e);
        }
    }

    /**
     * 分配上架任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult assignTask(Long id, String assignedTo, String operator) {
        try {
            // 查询任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(id);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 只有待上架状态才能分配
            if (!"0".equals(task.getTaskStatus())) {
                return AjaxResult.error("只有待上架状态的任务才能分配");
            }

            // 分配任务
            int rows = putawayTaskMapper.assignTask(id, assignedTo, operator);
            if (rows <= 0) {
                return AjaxResult.error("分配任务失败");
            }

            // 更新任务状态为上架中
            putawayTaskMapper.updateTaskStatus(id, "1", operator);

            return AjaxResult.success("分配任务成功");
        } catch (Exception e) {
            throw new RuntimeException("分配任务异常：" + e.getMessage(), e);
        }
    }

    /**
     * PDA上架确认
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult confirmPutaway(Long taskId, BigDecimal putawayQuantity,
                                    String locationCode, String operator) {
        try {
            // 参数校验
            if (taskId == null) {
                return AjaxResult.error("任务ID不能为空");
            }
            if (putawayQuantity == null || putawayQuantity.compareTo(BigDecimal.ZERO) <= 0) {
                return AjaxResult.error("上架数量必须大于0");
            }
            if (StringUtils.isEmpty(locationCode)) {
                return AjaxResult.error("储位编码不能为空");
            }

            // 查询任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(taskId);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 计算已上架数量
            BigDecimal currentPuted = task.getPutedQuantity();
            BigDecimal newPuted = currentPuted.add(putawayQuantity);

            // 检查是否超量
            if (newPuted.compareTo(task.getPutawayQuantity()) > 0) {
                return AjaxResult.error("上架数量超过待上架数量");
            }

            // 创建上架明细
            WmsPutawayDetailEntity detail = new WmsPutawayDetailEntity();
            detail.setPutawayTaskId(taskId);
            detail.setPutawayTaskNo(task.getPutawayTaskNo());
            detail.setLocationId(locationCode); // 简化处理
            detail.setLocationCode(locationCode);
            detail.setLocationName(locationCode);
            detail.setPutawayQuantity(putawayQuantity);
            detail.setOperator(operator);
            detail.setOperateTime(new Date());
            detail.setCreateBy(operator);
            detail.setCreateTime(new Date());

            int rows = putawayDetailMapper.insertPutawayDetail(detail);
            if (rows <= 0) {
                return AjaxResult.error("创建上架明细失败");
            }

            // 更新任务已上架数量
            putawayTaskMapper.updatePutedQuantity(taskId, newPuted);

            // 更新实际储位（取最后一次上架的储位）
            putawayTaskMapper.updateActualLocation(taskId, locationCode, locationCode);

            // 判断是否完成
            if (newPuted.compareTo(task.getPutawayQuantity()) >= 0) {
                putawayTaskMapper.updateTaskStatus(taskId, "2", operator); // 2已上架
                task.setPutawayBy(operator);
                task.setPutawayTime(new Date());
                putawayTaskMapper.updatePutawayTask(task);
            } else {
                putawayTaskMapper.updateTaskStatus(taskId, "1", operator); // 1上架中
            }

            return AjaxResult.success("上架确认成功");
        } catch (Exception e) {
            throw new RuntimeException("上架确认异常：" + e.getMessage(), e);
        }
    }

    /**
     * 完成上架任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeTask(Long id, String operator) {
        try {
            // 查询任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(id);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 检查是否已完全上架
            if (task.getPutedQuantity().compareTo(task.getPutawayQuantity()) < 0) {
                return AjaxResult.error("上架数量未达到要求，无法完成任务");
            }

            // 更新任务状态
            int rows = putawayTaskMapper.updateTaskStatus(id, "2", operator);
            if (rows <= 0) {
                return AjaxResult.error("更新任务状态失败");
            }

            return AjaxResult.success("完成上架任务成功");
        } catch (Exception e) {
            throw new RuntimeException("完成上架任务异常：" + e.getMessage(), e);
        }
    }

    /**
     * 删除上架任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deletePutawayTask(Long id, String operator) {
        try {
            // 查询任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(id);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 只有待上架状态才能删除
            if (!"0".equals(task.getTaskStatus())) {
                return AjaxResult.error("只有待上架状态的任务才能删除");
            }

            // 删除明细
            putawayDetailMapper.deletePutawayDetailByTaskId(id);

            // 删除主表
            int rows = putawayTaskMapper.deletePutawayTaskById(id);
            if (rows <= 0) {
                return AjaxResult.error("删除上架任务失败");
            }

            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            throw new RuntimeException("删除上架任务异常：" + e.getMessage(), e);
        }
    }

    // ========== 私有辅助方法 ==========

    /**
     * 生成上架任务号
     */
    private String generatePutawayTaskNo() {
        return "PUT" + DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS);
    }

    /**
     * 上架异常处理（新增方法）
     * 将收货单状态回滚至「4 - 异常」，记录异常原因、人员、时间
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult handlePutawayException(Long taskId, String exceptionReason,
                                           String exceptionDesc, String photoUrls, String operator) {
        try {
            // 1. 查询上架任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(taskId);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 2. 更新上架任务状态为异常（9）
            task.setTaskStatus("9"); // 异常状态
            task.setUpdateBy(operator);
            task.setUpdateTime(new Date());

            int rows = putawayTaskMapper.updatePutawayTask(task);
            if (rows <= 0) {
                return AjaxResult.error("更新上架任务状态失败");
            }

            // 3. 更新收货单状态为异常（4）
            int orderRows = receiveOrderMapper.updateReceiveOrderStatus(
                task.getReceiveOrderId(), "4", operator);
            if (orderRows <= 0) {
                return AjaxResult.error("更新收货单状态失败");
            }

            // 4. 创建异常记录
            try {
                String exceptionTitle = "上架异常：" + task.getPutawayTaskNo();
                String fullExceptionDesc = "上架任务[" + task.getPutawayTaskNo() + "]发生异常，原因：" + exceptionReason;
                if (exceptionDesc != null && !exceptionDesc.isEmpty()) {
                    fullExceptionDesc += "，详细描述：" + exceptionDesc;
                }

                AjaxResult exceptionResult = exceptionRecordService.createExceptionRecord(
                    "putaway_error", // 异常类型：上架异常
                    "putaway_task", // 关联单据类型：上架任务
                    task.getPutawayTaskNo(), // 关联单据号
                    taskId, // 关联单据ID
                    exceptionTitle, // 异常标题
                    fullExceptionDesc, // 异常描述
                    exceptionReason, // 异常原因
                    operator // 操作人
                );

                if (!exceptionResult.isSuccess()) {
                    // 异常记录创建失败不回滚主业务，只记录日志
                    System.err.println("创建异常记录失败：" + exceptionResult.get("Msg"));
                }
            } catch (Exception e) {
                // 异常记录创建失败不回滚主业务，只记录日志
                System.err.println("创建异常记录异常：" + e.getMessage());
            }

            return AjaxResult.success("上架异常处理成功，状态已更新为异常", task.getPutawayTaskNo());

        } catch (Exception e) {
            throw new RuntimeException("上架异常处理失败：" + e.getMessage(), e);
        }
    }

    /**
     * 重置上架任务状态（新增方法）
     * 将异常状态的上架任务重新设置为待上架状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult resetPutawayTaskStatus(Long taskId, String operator) {
        try {
            // 1. 查询上架任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(taskId);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 只有异常状态才能重置
            if (!"9".equals(task.getTaskStatus())) {
                return AjaxResult.error("只有异常状态的上架任务才能重置，当前状态：" + task.getTaskStatus());
            }

            // 2. 更新上架任务状态为待上架（0）
            task.setTaskStatus("0"); // 待上架状态
            task.setPutedQuantity(BigDecimal.ZERO); // 重置已上架数量
            task.setActualLocationCode(null); // 清空实际储位
            task.setUpdateBy(operator);
            task.setUpdateTime(new Date());

            int rows = putawayTaskMapper.updatePutawayTask(task);
            if (rows <= 0) {
                return AjaxResult.error("更新上架任务状态失败");
            }

            // 3. 删除该任务的上架明细记录（重新开始）
            putawayDetailMapper.deletePutawayDetailByTaskId(taskId);

            // 4. 更新收货单状态为已验收（2）- 回到上架前状态
            receiveOrderMapper.updateReceiveOrderStatus(
                task.getReceiveOrderId(), "2", operator);

            return AjaxResult.success("重置上架任务状态成功，任务可重新执行");

        } catch (Exception e) {
            throw new RuntimeException("重置上架任务状态失败：" + e.getMessage(), e);
        }
    }

    /**
     * 强制完成上架任务（新增方法）
     * 用于处理特殊情况下的上架任务强制完成
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult forceCompletePutaway(Long taskId, String reason, String operator) {
        try {
            // 1. 查询上架任务
            WmsPutawayTaskEntity task = putawayTaskMapper.selectPutawayTaskById(taskId);
            if (task == null) {
                return AjaxResult.error("上架任务不存在");
            }

            // 2. 强制完成上架任务
            task.setTaskStatus("2"); // 已上架状态
            task.setPutedQuantity(task.getPutawayQuantity()); // 设置已上架数量等于待上架数量
            task.setPutawayBy(operator);
            task.setPutawayTime(new Date());
            task.setUpdateBy(operator);
            task.setUpdateTime(new Date());

            // 添加强制完成备注
            String remark = task.getRemark() != null ? task.getRemark() : "";
            remark += "[" + new Date() + "] 强制完成，原因：" + reason + "，操作人：" + operator;
            task.setRemark(remark);

            int rows = putawayTaskMapper.updatePutawayTask(task);
            if (rows <= 0) {
                return AjaxResult.error("强制完成上架任务失败");
            }

            return AjaxResult.success("强制完成上架任务成功");

        } catch (Exception e) {
            throw new RuntimeException("强制完成上架任务失败：" + e.getMessage(), e);
        }
    }
}
